package com.tyc.threalpool;

import java.util.concurrent.*;

/**
 * 线程池出现异常怎么处理：异常线程运行结束销毁、创建新的线程
 * 线程池运行任务出现异常主线程无法捕获解决方案？
 *      1、利用 CompletableFuture
 *      2. 自定义 ThreadFactory
 * @author tyc
 * @version 1.0
 * @date 2023-01-05 16:32:19
 */
public class Demo01 {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(3);
        try {
            executor.execute(()->{
                System.out.println(1/0);
            });
        } catch (Exception e) {
            System.out.println("捕获不到异常");
        }

        // 方案1
        CompletableFuture.runAsync(()->{
            System.out.println(1/0);
        }).exceptionally(throwable -> {
            System.out.println("方案1-捕获到了异常");
            return null;
        });

        // 方案2 自定义线程工厂
        ThreadPoolExecutor executor1 = new ThreadPoolExecutor(3, 3, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5), new MyThreadFactory());

        executor1.execute(()->{
            System.out.println(1/0);
        });

        // 方案3 重写ThreadPoolExecutor的afterExecute方法
        ThreadPoolExecutor executor2 = new MyThreadPool(3, 3, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<>(5));
        executor2.execute(()->{
            System.out.println(1/0);
        });

    }

    static class MyThreadPool extends ThreadPoolExecutor{
        public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }

        public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory);
        }

        public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        }

        public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        }

        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            if(t != null){
                System.out.println("方案3-捕获到了异常");
                System.out.println("重新提交任务");
                execute(r);
            }
        }
    }


    static class MyThreadFactory implements ThreadFactory{
        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setUncaughtExceptionHandler((t,e)->{
                System.out.println("方案2-捕获到异常");
            });
            return thread;
        }
    }
}
